<template>
  <button
    type="button"
    :class="buttonClasses"
    :disabled="disabled || loading"
    v-bind="$attrs"
    @click="handleClick"
    @mousedown="handleMouseDown"
    @mouseup="handleMouseUp"
    @mouseleave="handleMouseLeave"
    @focus="handleFocus"
    @blur="handleBlur"
    ref="buttonRef"
  >
    <!-- 加载状态 -->
    <div v-if="loading" class="flex items-center justify-center">
      <div class="animate-spin rounded-full h-4 w-4 border-b-2 border-current mr-2"></div>
      <span>{{ loadingText }}</span>
    </div>

    <!-- 正常状态 -->
    <div v-else class="flex items-center justify-center">
      <slot />
    </div>
  </button>
</template>

<script setup lang="ts">
  import { computed, ref, useSlots } from 'vue'

  interface Props {
    variant?:
      | 'primary'
      | 'secondary'
      | 'outline'
      | 'ghost'
      | 'danger'
      | 'close'
      | 'default'
      | 'ai'
      | 'fictional'
    size?: 'sm' | 'md' | 'lg' | 'xl'
    shape?: 'square' | 'rounded' | 'circle'
    disabled?: boolean
    loading?: boolean
    loadingText?: string
    fullWidth?: boolean
    persistentFocus?: boolean
  }

  const props = withDefaults(defineProps<Props>(), {
    variant: 'primary',
    size: 'md',
    shape: 'rounded',
    disabled: false,
    loading: false,
    loadingText: '加载中...',
    fullWidth: false,
    persistentFocus: false,
  })

  const emit = defineEmits<{
    click: [event: MouseEvent]
  }>()

  const slots = useSlots()

  // 交互状态管理
  const isActive = ref(false)
  const isFocused = ref(false)
  const buttonRef = ref<HTMLButtonElement>()

  // 判断是否为图标按钮
  const isIconButton = computed(() => {
    // 检查默认插槽的内容
    const defaultSlot = slots.default?.()
    if (!defaultSlot) return false

    // 如果插槽内容只有一个元素且是SVG，则认为是图标按钮
    if (defaultSlot.length === 1) {
      const firstChild = defaultSlot[0]
      if (firstChild.type === 'svg') {
        return true
      }
    }

    // 如果插槽内容包含文本，则认为是普通按钮
    const hasText = defaultSlot.some(
      (child) =>
        typeof child === 'string' ||
        (typeof child === 'object' && child.children && typeof child.children === 'string'),
    )

    return !hasText
  })

  // 按钮样式类
  const buttonClasses = computed(() => {
    const baseClasses = [
      'inline-flex items-center justify-center font-medium transition-all duration-normal ease-out disabled:opacity-50 disabled:cursor-not-allowed select-none',
      props.fullWidth && !isIconButton.value ? 'w-full' : '',
    ]

    // 焦点样式 - 根据persistentFocus属性决定
    const focusClasses = props.persistentFocus
      ? 'focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-background-900'
      : 'focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-background-900 focus:ring-opacity-30'

    // 形状样式
    const shapeClasses = {
      square: 'rounded-none',
      rounded: isIconButton.value
        ? {
            sm: 'rounded-md',
            md: 'rounded-lg',
            lg: 'rounded-lg',
            xl: 'rounded-xl',
          }[props.size]
        : {
            sm: 'rounded-md',
            md: 'rounded-lg',
            lg: 'rounded-lg',
            xl: 'rounded-xl',
          }[props.size],
      circle: 'rounded-full',
    }

    // 尺寸样式 - 根据是否为图标按钮决定
    const sizeClasses = isIconButton.value
      ? {
          sm: 'w-8 h-8 text-sm',
          md: 'w-10 h-10 text-base',
          lg: 'w-12 h-12 text-lg',
          xl: 'w-14 h-14 text-xl',
        }
      : {
          sm: 'px-3 py-1.5 text-sm',
          md: 'px-4 py-2 text-sm',
          lg: 'px-6 py-3 text-base',
          xl: 'px-8 py-4 text-lg',
        }

    // 统一的变体样式 - 使用新的颜色规范
    const variantClasses = {
      primary: `text-white shadow-sm ${
        isActive.value
          ? 'bg-primary-800 shadow-inner'
          : 'bg-primary-600 hover:bg-primary-700 focus:ring-primary-500 shadow-neon'
      }`,
      secondary: `text-text-primary shadow-sm ${
        isActive.value
          ? 'bg-background-600 shadow-inner'
          : 'bg-background-700 hover:bg-background-600 focus:ring-background-500 border border-background-600'
      }`,
      outline: `border border-background-600 bg-transparent text-text-primary ${
        isActive.value
          ? 'bg-background-700 text-text-primary border-primary-500'
          : 'hover:bg-background-800 hover:text-text-primary focus:ring-primary-500'
      }`,
      ghost: `bg-transparent text-text-secondary ${
        isActive.value
          ? 'bg-background-700 text-text-primary'
          : 'hover:bg-background-800 hover:text-text-primary focus:ring-primary-500'
      }`,
      danger: `text-white shadow-sm ${
        isActive.value ? 'bg-error shadow-inner' : 'bg-error hover:bg-error/90 focus:ring-error'
      }`,
      close: `text-text-primary shadow-sm ${
        isActive.value
          ? 'bg-background-600 shadow-inner'
          : 'bg-background-800 hover:bg-background-700 focus:ring-background-500'
      }`,
      default: `bg-background-800 text-text-primary shadow-sm ${
        isActive.value
          ? 'bg-background-600 shadow-inner'
          : 'hover:bg-background-700 focus:ring-background-500'
      }`,
      ai: `text-white shadow-sm ${
        isActive.value
          ? 'bg-ai-generated shadow-inner'
          : 'bg-ai-generated hover:bg-ai-generated/90 focus:ring-ai-generated shadow-neon-purple'
      }`,
      fictional: `text-white shadow-sm ${
        isActive.value
          ? 'bg-fictional shadow-inner'
          : 'bg-fictional hover:bg-fictional/90 focus:ring-fictional shadow-neon-pink'
      }`,
    }

    return [
      ...baseClasses,
      focusClasses,
      sizeClasses[props.size],
      shapeClasses[props.shape],
      variantClasses[props.variant],
    ].join(' ')
  })

  const handleClick = (event: MouseEvent) => {
    if (!props.disabled && !props.loading) {
      emit('click', event)
      // 如果不保持焦点，点击后立即移除焦点
      if (!props.persistentFocus) {
        // 使用setTimeout确保在事件循环的下一个tick中移除焦点
        setTimeout(() => {
          buttonRef.value?.blur()
        }, 0)
      }
    }
  }

  const handleMouseDown = () => {
    if (!props.disabled && !props.loading) {
      isActive.value = true
    }
  }

  const handleMouseUp = () => {
    isActive.value = false
  }

  const handleMouseLeave = () => {
    isActive.value = false
  }

  const handleFocus = () => {
    isFocused.value = true
  }

  const handleBlur = () => {
    isFocused.value = false
  }
</script>
